package diploma.vizualizacija;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.InvocationTargetException;
import java.lang.ArrayIndexOutOfBoundsException;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import diploma.matrika.MatrikaParov;
import diploma.matrika.data.Par;
import diploma.substitucija.Buffer;
import diploma.substitucija.Substitucija;
import diploma.tokenizer.Tokenizer;

public class Vizualizacija extends JFrame 
{
	
	public static class VisualMatrix extends JPanel
	{

		private static final int	ST_MAX_PAROV	= 60;
		double maxValue;
		MatrikaParov matP = null;
		String ime;
		List<Par> lstMaxPari;
		float minParValue;
		
		int stVrstica[] = new int[MatrikaParov.MAX_PAROV];
		int stStolpec[] = new int[MatrikaParov.MAX_PAROV];
		
		public VisualMatrix(MatrikaParov mat, String ime) 
		{
			setPreferredSize(new Dimension(500, 500));
			this.ime = ime;
			matP = mat;
			
		}
		
		public void paint(Graphics g) 
		{
			maxValue = matP.maxPar().frekvenca;
			lstMaxPari = matP.najdiMaxPare(ST_MAX_PAROV);
			stVrstica= new int[MatrikaParov.MAX_PAROV];
			stStolpec = new int[MatrikaParov.MAX_PAROV];
			for(Par p : lstMaxPari)
			{
				int v = MatrikaParov.getIndex(p.par.charAt(0))-1;
				int s = MatrikaParov.getIndex(p.par.charAt(1))-1;
				stVrstica[v]++;
				stStolpec[s]++;
			}
			float boxSize = getPreferredSize().width / (MatrikaParov.MAX_PAROV+2); //en box je tok visok kot ena vrstica, širok kot ena vrstica
			float masterOffX = boxSize;
			float masterOffY = boxSize;
			for(int v = 1; v < MatrikaParov.MAX_PAROV; v++)
			{
				for(int s = 1; s < MatrikaParov.MAX_PAROV; s++) //pobarva use
				{
					float px = (s-1) * boxSize; //kje se nahajamo, velikost enga kvadratka
					float py = (v-1) * boxSize;
					//Treba se odločit s katero barvo barvamo
					double odstotekBarve = (1 - matP.frekvencaParov[v][s] / maxValue)*255d; 
					int cc = Math.min((int)odstotekBarve , 255);
					g.setColor(new Color(cc, cc, cc));
					g.fillRect((int)(px+masterOffX), (int)(py+masterOffY), (int)boxSize, (int)boxSize);//fillRect pobarva pravokotnik na poziciji px,py. Velikost pravokotnika(višina, dolžina je enaka boxSize.
					g.setColor(Color.black); //Določi trenutno barvo katero bodo uporabile vse nadalne operacoije risanja, drugac uporabi isto intenziteto barve s katero je  bil obarvan kvadratek
					g.drawRect((int)(px+masterOffX), (int)(py+masterOffX), (int)boxSize, (int)boxSize);//izriše samo silhueto pravokotnika 
				}
			}
			
			for(Par p : lstMaxPari) 
			{
				float py = (MatrikaParov.getIndex(p.par.charAt(0))-1) * boxSize;
				float px = (MatrikaParov.getIndex(p.par.charAt(1))-1) * boxSize;
				g.setColor(Color.red);
				g.fillRect((int)(px+masterOffX), (int)(py+masterOffX), (int)boxSize/2, (int)boxSize/2);
				g.setColor(Color.black);//obroba rdečga kvadratka
				g.drawRect((int)(px+masterOffX), (int)(py+masterOffX), (int)boxSize/2, (int)boxSize/2);
			}
			//Izrišemo karakterje!
			
			//Izpis črk
			int stevilkeOff = (int)(boxSize * (Substitucija.tabela.length + 1));
			for(int i = 0; i < Substitucija.tabela.length; i++)
			{
				int offset = (int)(boxSize * (i + 1));
				int offsetY = (int)(boxSize);

				//Izrišemo črke
				g.drawChars(Substitucija.tabela, i, 1, 3, offset+offsetY-3);
				g.drawChars(Substitucija.tabela, i, 1, offset+3, -2+offsetY);
				
				//Izrišemo pare
				g.drawString(""+stVrstica[i], stevilkeOff + 3, offset+offsetY-3);
				g.drawString(""+stStolpec[i], offset+3, (int)(boxSize + stevilkeOff));
			}
			//Izpis frekvenc max parov
		}
	}
	
	JScrollPane scrollPane;
	JPanel viewPort ;
	int stParov;
	
	public Vizualizacija() {
		super("Matrike pogostosti pojavljanja");
		scrollPane = new JScrollPane();
		setLayout(new BorderLayout());
		
		viewPort = new JPanel();
		scrollPane.setViewportView(viewPort);
		add(BorderLayout.CENTER, scrollPane);
		setSize(new Dimension(1800,800));
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
	}
	
	public void dodajPogled(MatrikaParov mat, String ime)
	{
		//Doda nov pogled na viewPort
		{
			VisualMatrix vm = new VisualMatrix(mat, ime);
			JPanel panSkupi = new JPanel(new BorderLayout());
			panSkupi.add(BorderLayout.CENTER, vm);
			JLabel napis = new JLabel(ime);
			
			JPanel panCenter = new JPanel(new FlowLayout(FlowLayout.CENTER ));
			panCenter.add( napis);
	
			//
			panSkupi.add(BorderLayout.SOUTH, panCenter);
			viewPort.add(panSkupi);
		}
		
		viewPort.revalidate();
		scrollPane.revalidate();
	}
	
	static MatrikaParov matSlovar;
	static MatrikaParov matTekst;
	static MatrikaParov matTekstPremesan2;
	static MatrikaParov matTekstPremesan;
	static MatrikaParov matPremesanSlovat;
	
	public static void main(String[] args) throws FileNotFoundException, InterruptedException, InvocationTargetException {
		
		StringBuffer txtSlovar = Buffer.file2Buffer(new File("slovar-sl.txt"));
		
		matSlovar = new MatrikaParov();
		List<String> lstBesedeSlovarja = Tokenizer.bufferToList(txtSlovar);
		System.out.println("Št. besed slovarja: " + lstBesedeSlovarja.size());
		matSlovar.posodobiFrekvence(lstBesedeSlovarja);

		matSlovar.izpisiMatriko();//najprej preberemo vrstico nato stolpec

		matSlovar.izpisiMatriko();//najprej preberemo vsrtico nato stolpec 

		
		Par maxPar = matSlovar.maxPar();
		System.out.println(maxPar.toString());
		System.out.println("Ali je res maksimalen? " + matSlovar.testirajMax(maxPar.frekvenca));
		
		Substitucija premesanSlovar = new Substitucija();
		StringBuffer txtPremesanSlovar =  premesanSlovar.naključnaSubstitucija(txtSlovar);
		matPremesanSlovat = new MatrikaParov();
		matPremesanSlovat.posodobiFrekvence(Tokenizer.bufferToList(txtPremesanSlovar));
		
		System.out.println("Premešan slovar");
		maxPar = matPremesanSlovat.maxPar();
		System.out.println(maxPar.toString());
		System.out.println("Ali je res maksimalen? " + matPremesanSlovat.testirajMax(maxPar.frekvenca));
		
		
		StringBuffer txtTest = Buffer.file2Buffer(new File("slovar-sl.txt"));
		matTekst = new MatrikaParov();
		matTekst.posodobiFrekvence(Tokenizer.bufferToList(txtTest));
		
		Substitucija s2 = new Substitucija();
		StringBuffer txtTestPremesan2 = s2.naključnaSubstitucijaEnegaPara(txtTest);
		matTekstPremesan2 = new MatrikaParov();
		matTekstPremesan2.posodobiFrekvence(Tokenizer.bufferToList(txtTestPremesan2));
		
		StringBuffer txtTestPremesan = s2.naključnaSubstitucija(txtTest);
		matTekstPremesan = new MatrikaParov();
		matTekstPremesan.posodobiFrekvence(Tokenizer.bufferToList(txtTestPremesan));
		
		System.out.println("Max 26 parov");
		List<Par> lstPari = matSlovar.najdiMaxPare(35);
		for(Par p :lstPari)
		{
			System.out.println(p);
		}

		Vizualizacija viz = new Vizualizacija();
		viz.dodajPogled(matSlovar, "Frekvence slovarja");
		viz.dodajPogled(matPremesanSlovat, "Frekvence premešanega slovarja");
		viz.dodajPogled(matTekst, "Frekvence besedila");
		viz.dodajPogled(matTekstPremesan2, "Substitucija enega para v besedilu");
		viz.dodajPogled(matTekstPremesan, "Frekvence premešanega besedila");
		viz.repaint();
		
	}
}
